home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
asmbler.arc
/
DDIIL.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-11-19
|
9KB
|
272 lines
PUBLIC DDIIL
ASSUME CS:$DDIIL
INCLUDE DOS.INC
$DDIIL SEGMENT PARA PUBLIC 'CODE'
COMMENT \ Procedure/Function : DDIIL
PROCEDURE DDISB (MX,MY : integer); EXTERNAL;
PROCEDURE DDIIL (IX0,IY0,IX1,IY1 : integer; VISBLE : boolean);
{
(Incremental Line)
Fill in the steps on the plot frame between the point (IX0,IY0) and
(IX1,IY1), where IX0, IY0, IX1, and IY1 are in actual raster units for
the device being used. If a vector plot device is to be used, this
routine might instead simply transmit a single vector to a buffer.
This version uses a symmetric DDA algorithm due to Van Throng (?).
(25-JAN-84)
}
VAR
AXIS, AXISX, AXISY, BIAS, DELX, DELY, DIAG, DIAGX, DIAGY, I, IX,
IY, NDIST, NUMPNT, SX, SY : INTEGER;
Here is the Pascal code corresponding to the assembly code below. Line
number labels are retained, but hand optimization of the .COD file
produced by the IBM Pascal Version 1.00 compiler for the IBM PC with the
debug code suppressed has substantially reduced the code size and
resulted in some minor rearrangements.
L44: IF VISBLE THEN
L45: BEGIN
L46: DELX := IX1 - IX0;
L47: DELY := IY1 - IY0;
L48: SX := ABS(DELY);
L49: SY := ABS(DELX);
L50: IF DELX >= 0
L51: THEN DIAGX := 1
L52: ELSE DIAGX := -1;
L53: IF DELY >= 0
L54: THEN DIAGY := 1
L55: ELSE DIAGY := -1;
L56: IF SY <= SX THEN
L57: BEGIN
L58: AXISX := 0;
L59: AXISY := DIAGY
L60: END
L61: ELSE
L62: BEGIN
L63: AXISX := DIAGX;
L64: AXISY := 0
L65: END;
L66: AXIS := MIN(SX,SY);
L67: BIAS := MAX(SX,SY);
L68: DIAG := AXIS - BIAS;
L69: IF DIAGX < 0
L70: THEN NDIST := - BIAS - 2
L71: ELSE NDIST := - BIAS - 1;
L72: NDIST := AXIS + NDIST DIV 2;
L73: NUMPNT := MAX(SX,SY) + 1;
L74: IX := IX0;
L75: IY := IY0;
L76: FOR I := 1 TO NUMPNT-1 DO
L77: BEGIN
L78: DDISB (IX,IY);
L79: IF NDIST < 0 THEN
L80: BEGIN
L81: NDIST := NDIST + AXIS;
L82: IX := IX + AXISX;
L83: IY := IY + AXISY
L84: END
L85: ELSE
L86: BEGIN
L87: NDIST := NDIST + DIAG;
L88: IX := IX + DIAGX;
L89: IY := IY + DIAGY
L90: END
L91: END;
L92: DDISB(IX,IY)
L93: END
L94: END; { DDIIL }
\
ARGCNT EQU 5 ; Number of arguments
IX0 EQU [BP] ; Define symbolic argument frame offsets
IY0 EQU [BP-2]
IX1 EQU [BP-4]
IY1 EQU [BP-6]
VISBLE EQU [BP-8]
; return address as CS:offset at [BP-10..13]
; old BP at [BP-14..15]
AXISX EQU [BP-16] ; start of local variables
AXISY EQU [BP-18]
BIAS EQU [BP-20]
DELX EQU [BP-22]
DELY EQU [BP-24]
DIAG EQU [BP-26]
DIAGX EQU [BP-28]
DIAGY EQU [BP-30]
I EQU [BP-32]
IX EQU [BP-34]
IY EQU [BP-36]
NDIST EQU [BP-38]
NUMPNT EQU [BP-40]
SX EQU [BP-42]
SY EQU [BP-44]
AXIS EQU [BP-46]
SPBIAS EQU 46 ; New SP points at last local stack variable
DDIIL PROC FAR
PUSH BP ; Save caller's frame pointer
MOV BP,SP ; and set up our own.
ADD BP,4+2*ARGCNT ; Point to top of arg list on stack
SUB SP,SPBIAS ; Reserve space for locals on stack
; (stack overflow not checked for)
L44:
MOV DX,VISBLE
TEST DL,DL ; VISBLE = false?
JNZ L46 ; No
ADD SP,SPBIAS ; Yes, restore original SP at entry
POP BP ; and caller's frame pointer
RET 2*ARGCNT ; and return discarding stack arguments
L46:
MOV DX,IX1
SUB DX,IX0
MOV DELX,DX ; DELX := IX1 - IX0
L47:
MOV DX,IY1
SUB DX,IY0
MOV DELY,DX ; DELY := IY1 - IY0
L48:
MOV DX,DELY
MOV CX,1
TEST DX,DX ; DELY < 0?
JNS L48a ; No
NEG DX ; Yes, make positive
NEG CX ; -1
L48a:
MOV SX,DX ; SX := ABS(DELY)
MOV DIAGY,CX ; DIAGY := SIGN(1,DELY)
L49:
MOV DX,DELX
MOV CX,1
TEST DX,DX ; DELX < 0?
JNS L49a ; No
NEG DX ; Yes, make positive
NEG CX ; -1
L49a:
MOV SY,DX ; SY := ABS(DELX)
MOV DIAGX,CX ; DIAGX := SIGN(1,DELX)
L50:
L51:
L52:
L53:
L54:
L55:
L56:
MOV DX,SY
CMP DX,SX ; SY > SX?
JG I12 ; Yes
L58: ; No, SY <= SX
MOV word ptr AXISX,0000H ; AXISX := 0
L59:
MOV DX,DIAGY
MOV AXISY,DX ; AXISY := DIAGY
JMP short I13
I12: ; else (SY > SX)
L63:
MOV DX,DIAGX
MOV AXISX,DX ; AXISX := DIAGX
L64:
MOV word ptr AXISY,0000H ; AXISY := 0
L65:
I13:
L66:
MOV DX,SX
MOV CX,SY
CMP DX,CX ; SX > SY?
JG L66a ; Yes
MOV AXIS,DX ; No, AXIS = min(SX,SY) = SX
MOV BIAS,CX ; and BIAS = max(SX,SY) = SY
JMP SHORT L68
L66a:
MOV AXIS,CX ; No, AXIS = min(SX,SY) = SY
MOV BIAS,DX ; and BIAS = max(SX,SY) = SX
L68:
MOV DX,AXIS
SUB DX,BIAS
MOV DIAG,DX ; DIAG := AXIS - BIAS
L69:
MOV DX,BIAS
NEG DX ; -BIAS
DEC DX ; -BIAS-1
CMP word ptr DIAGX,0000H ; DIAGX < 0?
JGE I14 ; No
L70:
DEC DX ; Yes, form -BIAS-2
I14:
L71:
MOV NDIST,DX ; NDIST is always negative
L72:
NEG DX ; -NDIST is positive
SAR DX,1 ; ((-NDIST) DIV 2)
NEG DX ; (NDIST DIV 2)
ADD DX,AXIS ; (NDIST DIV 2) + AXIS
MOV NDIST,DX ; NDIST := AXIS + NDIST DIV 2
L73:
MOV DX,SX
CMP DX,SY ; SX >= SY?
JGE L73a ; Yes
MOV DX,SY ; MAX(SX,SY)
L73a:
INC DX ; MAX(SX,SY) + 1
MOV NUMPNT,DX ; NUMPNT := MAX(SX,SY) + 1
; Allocate IX, IY, I, NDIST to registers CX, DX, SI, and DI, and set
; video function codes in AH,AL outside of loop
L74:
MOV CX,IX0 ; IX := IX0
L75:
MOV DX,IY0 ; IY := IY0
L76:
MOV SI,0001H ; I := 1
MOV DI,NDIST
MOV AL,81H ; want exclusive-OR with current color
MOV AH,$VIDEO_SETDOT ; code to set a dot in video map
I18: ; Start of loop over I
CMP SI,NUMPNT ; I < NUMPNT?
JGE I17 ; No, exit loop
L78:
INT $VIDEO ; set the dot
L79:
TEST DI,DI ; NDIST < 0?
JGE I19 ; No
L81:
ADD DI,AXIS ; Yes, NDIST := NDIST + AXIS
L82:
ADD CX,AXISX ; IX := IX +AXISX
L83:
ADD DX,AXISY ; IY := IY + AXISY
INC SI ; I := I + 1 for next iteration
JMP short I18 ; Loop back to test limits
I19:
L87: ; here when NDIST >= 0
ADD DI,DIAG ; NDIST := NDIST + DIAG
L88:
ADD CX,DIAGX ; IX := IX + DIAGX
L89:
ADD DX,DIAGY ; IY := IY + DIAGY
INC SI ; I := I + 1 for next iteration
JMP short I18 ; Loop back to test limits
I17:
L92: ; here at loop end to set final dot
INT $VIDEO ; set the dot ((CX,DX) = (IX,IY) = (col,row))
I7: ; here when done
ADD SP,SPBIAS ; Restore original SP at entry
POP BP ; and caller's frame pointer
RET 2*ARGCNT ; and return discarding stack arguments
DDIIL ENDP
$DDIIL ENDS
END